package com.ww.juc.forkjoin;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 基于ThreadPoolTest进行修改
 *
 * @author wanggw
 * @date 2022-08-31 18:30:36
 */
public class ThreadPoolTestLearn {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        String directory = "D:/";
        System.out.println("目录：" + directory);

        // 创建线程池
        ExecutorService pool = Executors.newCachedThreadPool();
        MathCounter2 counter = new MathCounter2(new File(directory), pool);
        Future<Integer> result = pool.submit(counter);

        try {
            System.out.println("文件数：" + result.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        pool.shutdown();

        long end = System.currentTimeMillis();
        int largestPoolSize = ((ThreadPoolExecutor) pool).getLargestPoolSize();
        System.out.println("largest pool size=" + largestPoolSize + "耗时：" + (end - start) / 1000 + "s");
    }
}

class MathCounter2 implements Callable<Integer> {

    private File directory;
    private ExecutorService pool;
    private int count;

    public MathCounter2(File directory, ExecutorService pool) {
        this.directory = directory;
        this.pool = pool;
    }

    @Override
    public Integer call() throws Exception {
        System.out.println("进来了...");
        count = 0;
        try {
            File[] files = directory.listFiles();
            List<Future<Integer>> results = new ArrayList<>();

            for (File file : files) {
                if (file.isDirectory()) {
                    // 目录，继续向线程池提交
                    MathCounter2 counter = new MathCounter2(file, pool);
                    Future<Integer> result = pool.submit(counter);
                    results.add(result);
                } else {
                    count++;
                }
            }

            for (Future<Integer> result : results) {
                try {
                    count += result.get();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        } catch (InterruptedException e) {

        }
        return count;
    }
}
